﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Magiq.Support;

namespace Magiq.Query
{
    public class ExpressionSelectSplit
    {
        private static readonly MethodInfo[] SelectMethods = typeof(Enumerable).GetMethods()
            .Where(x => x.Name == "Select")
            .Union(typeof(Queryable).GetMethods()
                       .Where(x => x.Name == "Select"))
            .ToArray();

        public LambdaExpression Select { get; private set; }
        public Expression Rest { get; private set; }

        public static ExpressionSelectSplit From(Expression body)
        {
            var call = body as MethodCallExpression;
            var selectAndWhere = new ExpressionSelectSplit();
            if (call != null && call.Method.GetGenericMethodDefinition().In(SelectMethods))
            {
                var arg = call.Arguments[1];
                if (arg is UnaryExpression)
                    arg = ((UnaryExpression)arg).Operand;
                if (!(arg is LambdaExpression))
                    throw new InvalidOperationException(
                        "Insert using expressions should contain lambda expressions and not variables or method calls.");

                selectAndWhere.Select = (LambdaExpression) arg;
                selectAndWhere.Rest = call.Arguments[0];
                if (selectAndWhere.Select.Parameters.Count == 3)
                    throw new InvalidOperationException(
                        "Select(Expression<Func<TSource,int,TResult>> selector) override is not supported.)");
            }
            else
            {
                selectAndWhere.Rest = body;
            }

            return selectAndWhere;
        }
    }
}